import 'dart:async';

void main() {
  var grammarTest = DartGrammarTest();
  grammarTest.testGrammar();
}

class DartGrammarTest {
  void testGrammar() {
    var a = 'hello' ' ' 'ducafecat';
    var a1 = 'hello'
        ' '
        'ducafecat';
    print("onInit set=${a} a1=${a1}");
    var a3 = 'hello word \n this is multi line';
    //取消转义
    var a4 = r'hello word \n this is multi line';

    var d1 = new DateTime(2018, 10, 1);
    var d2 = new DateTime(2018, 10, 10);
    var difference = d1.difference(d2);
    //时间差
    print([difference.inDays, difference.inHours]);

    List<int> l = [];
    l
      ..add(1)
      ..add(2)
      ..add(3);

    print(l.indexOf(2));
    print(l.indexWhere((it) => it == 3));
    l.fillRange(0, 2, 6);
    print('List=>$l');

    //日期
    List<DateTime> listDateTime = [];
    listDateTime.addAll([
      DateTime.now(),
      DateTime.now().add(Duration(days: -10)),
      DateTime.now().add(Duration(days: -2)),
    ]);
    print("日期List=>$listDateTime");
    listDateTime.sort((a, b) => a.compareTo(b));
    print("日期List sort=>$listDateTime");

    // Set 是一个元素唯一的有序队列
    var set = new Set();
    set.add('java');
    set.add('php');
    set.add('python');
    set.add('java');
    set.add('sql');
    set.add('swift');
    set.add('dart');
    print("set=>${set}");

    print('add=>${add(1, 2)}');
    print('add3=>${add3(x: 2,z: 5)}');

    var make = makeAdd(10);
    print("调用返回值是函数的函数=>${make(6)}");
    print("直接调用返回值是函数的函数=>${makeAdd(10)(6)}");

    print('================操作符============');
    print(5/2);
    //除号，但是返回值为整数
    print(5~/2);
    print(5 % 2);

    bool isDone = false;
    while(!isDone) {
      print('is not done');
      isDone = true;
    }
    bool isRunning = true;
    do {
      print('is running');
      isRunning = false;
    } while (isRunning);

    //continue 指定位置
    String command = "close";
    switch(command) {
      case "open":
        print("open");
        break;
      case "close":
        print("close");
        continue doClose;
      doClose:
      case "doClose":
        print("DO_CLOSE");
        break;
      default:
        print("-----");
    }

    print('================异常============');
    try{
      throw new OutOfMemoryError();
    }on OutOfMemoryError{
      print('没有内存了');
      //重新抛出错误,捕获不了
      // rethrow;
    }catch(e){
      print(e);
    }finally{
      print('finally end');
    }

    print('================类============');
    var point = Point.fromJson({"x":1,"y":2});
    print([point.x,point.y]);
    print(Person()._name);

    var xm = Xiaomi();
    xm.startup();
    xm.shutdown();
    xm.sms();

    print("===============同步代码生成器===================");
    var iterable = naturalsTo(5).iterator;
    while(iterable.moveNext()) {
      print(iterable.current);
    }
    print("===============异步代码生成器===================");
    StreamSubscription streamSubscription = asyncNaturalsTo(5).listen((event) {
      print('listen event=${event}');
    });
    streamSubscription.onData((data) {
      print(data);
    });
    print("===============递归生成器========================");
    var iterator = naturalsDownFrom(5).iterator;
    while(iterator.moveNext()) {
      print(iterator.current);
    }
    var iterator2 = naturalsDownFrom2(5).iterator;
    while(iterator2.moveNext()) {
      print(iterator2.current);
    }
    print('typedef 用来保存函数的信息');
    compare();

    var where = l.where((element) => element>3);
    print('where test=>$where');


  }

  bool isValidString(String value, bool predicate(String string)) {
    return predicate(value);
  }


  Iterable<int> naturalsDownFrom2(int n) sync*{
    int k = n;
    int v = 0;
    print('递归start');
    while(v<n) {
      v++;
      yield k--;
    }
    print('递归end');
  }

  //yield* 以指针的方式传递递归对象，而不是整个同步对象
  Iterable<int> naturalsDownFrom(int n) sync*{
      if(n>0) {
        yield n;
        yield* naturalsDownFrom(n-1);
      }
  }

  // yield 会等待 moveNext 指令
  Iterable<int> naturalsTo(int n)sync*{
    print("start");
    int k = 0;
    while(k<n) {
      yield k++;
    }
    print('end');
  }
// 以流的方式一次性推送
// StreamSubscription 对象进行流监听控制
  Stream<int> asyncNaturalsTo(int n) async*{
    print('start');
    int k = 0;
    while(k<n) {
      yield k++;
    }
    print('end');
  }

  //可选参数
  int add(int x, [int? y, int? z]) {
    y = y ?? 1;
    z = z ?? 1;
    return x + y + z;
  }

  //可选参数 默认值
  int add2(int x, [int y = 2, int z = 3]) {
    return x + y + z;
  }

  //命名参数 默认值
  int add3({int x = 1, int y = 2, int z = 3}) {
    return x + y + z;
  }

  //Funcation 返回函数对象,Function可以不写
  Function makeAdd(int x){
    return (y) => x+y;
  }

}

class Point{
  num x;
  num y;
  Point(this.x,this.y);
  //重定向构造函数
  Point.fromJson(Map json) :this(json['x'],json['y']);
}
class Person{
  String? _name;
  set pName(String name)=>_name = name;
  String get pName=> "people is$_name";
}

abstract class Personal {
  static const String name = '';
  String age ="10";
  void printName();
}
class Teacher extends Personal{
  @override
  void printName() {

  }
}
//在Flutter中:
// class 就是 interface
// 当class被当做interface用时，class中的方法就是接口的方法，需要在子类里重新实现，在子类实现的时候要加@override
// 当class被当做interface用时，class中的成员变量也需要在子类里重新实现。在成员变量前加@override
// 实现接口可以有多个
class Student implements Personal{
  @override
  void printName() {
  }

  @override
  String age ='';
}


class Phone {
  void startup() {
    print('开机');
  }
  void shutdown() {
    print('关机');
  }
}

class AndroidPhone extends Phone {
  void startup() {
    super.startup();
    print('AndroidPhone 开机');
  }
}
class AndroidSystem {
  void call() {
    print('android call');
  }
}

class Weixin {
  void sms() {
    print('weixin sms');
  }
}

class QQ {
  void sms() {
    print('qq sms');
  }
}

class Xiaomi extends AndroidPhone with AndroidSystem, Weixin, QQ {
  void startup() {
    super.startup();
    print('AndroidPhone 开机');
  }
}

// 定义函数类型
typedef int Compare(Object a,Object b);

class SortedCollection{
  Compare compare;
  // 构造时传入函数
  SortedCollection(this.compare);
}
// 定义排序函数
int sort(Object a, Object b) => 0;

class SortedCollection2{
  Function? compare;

  //区别就是 typedef 编辑器会提示函数信息
  SortedCollection2(int compare(Object a,Object b)){
    this.compare = compare;
  }

}

void compare(){
  // 实例化传入
  SortedCollection coll = SortedCollection(sort);
  SortedCollection2 sortedCollection2 = SortedCollection2(sort);
  // 类型检查
  assert(coll.compare is Function);
  assert(coll.compare is Compare);
  assert(sortedCollection2.compare is Function);
  assert(sortedCollection2.compare is Compare);
}